

let cfg = require('./utils/cfg');
let webGlDebugUtil = require('./utils/webgl-debug');
let Fps = require('./fps');
let KeyInput = require('./input/keyInput');
let MouseInput = require('./input/mouseInput');
let Vec2 = require('./vec2');


let ActionMgr = require('./ActionMgr');
let Scheduler = require('./scheduler');

class GameApp{

    /**
     *
     * @param canvasEl
     * @param width
     * @param height
     * @param contentScale 缩放比例
     */
    constructor(canvasEl,width,height,contentScale = 1) {
        this._canvas = canvasEl;
        this._canvas.width = width;
        this._canvas.height = height;
        this._iContentScale = contentScale;

        // 使 canvas可以监听键盘事件
        this._canvas.setAttribute('tabindex',0);
        this._canvas.focus();

        let gl;
        if(cfg.Debug){
            gl  = webGlDebugUtil.makeDebugContext(this._canvas.getContext('webgl'));
        }else{
            gl  = this._canvas.getContext('webgl',{
                alpha:false
            });
        }

        gl.viewport(0,0,width,height);
        gl.clearColor(0.7,0.7,0.7,1.0);

        this._width = width * contentScale;
        this._height = height * contentScale;
        this._fps = new Fps();

        this._curScene = null;

        // init input
        this._keyInput = new KeyInput(this);
        this._mouseInput = new MouseInput(this);

        //
        cfg.init(gl,this);

        // action Mgr
        this._actionMgr = new ActionMgr();

        // scheduler
        this._scheduler = new Scheduler();
    }

    get scheduler(){
        return this._scheduler;
    }

    get actionMgr(){
        return this._actionMgr;
    }

    get fps(){
        return this._fps;
    }

    get width(){
        return this._width;
    }
    get height(){
        return this._height;
    }

    get canvas(){
        return this._canvas;
    }

    get scene(){
        return this._curScene;
    }

    /**
     *  返回的是webgl坐标系下的坐标
     * @param e {MouseEvent}
     * @returns {Vec2}
     */
    getPosFromEvent(e){
        let left = this._canvas.offsetLeft;
        let top = this._canvas.offsetTop;
        let x = e.clientX - left;
        let y = e.clientY - top;
        return new Vec2(x * this._iContentScale,this.height - this._iContentScale * y);
    }

    /**
     * 启动场景, 切换场景使用 replaceScene
     * @param scene
     */
    startWithScene(scene){
        this._curScene = scene;
        this._curScene.onEnable();
        this._mainLoop();
    }

    _mainLoop(){
        this._fps.calFpsAndDt();
        this._keyInput.pollEvents();
        this._checkKeyInput();

        this._actionMgr.update();
        this._scheduler.update();

        if(this._curScene){
            this._curScene.updateScene();
            this._curScene.renderScene();
        }
        requestAnimationFrame(this._mainLoop.bind(this));
    }

    // TODO:
    replaceScene(newScene){}  // eslint-disable-line

    // check key state
    _checkKeyInput(){
        if(this._curScene && this._curScene.onCheckKey){
            this._curScene.onCheckKey(this._keyInput);
        }
    }

    //-------------------------------------
    // input callback
    // mouse
    onMouseDown(e){
        if(this._curScene && this._curScene.onMouseDown){
            this._curScene.onMouseDown(e);
        }
    }

    onMouseMove(e){
        if(this._curScene && this._curScene.onMouseMove){
            this._curScene.onMouseMove(e);
        }
    }

    onMouseUp(e){
        if(this._curScene && this._curScene.onMouseUp){
            this._curScene.onMouseUp(e);
        }
    }


}

//----------------------------------
//  为了兼容之前的一些 API
Object.defineProperty(GameApp.prototype,'getDevWidth',{
    value:function(){
        return this._width;
    }
});

Object.defineProperty(GameApp.prototype,'getDevHeight',{
    value:function () {
        return this._height;
    }
});

Object.defineProperty(GameApp.prototype,'getCurScene',{
    value:function () {
        return this._curScene;
    }
});


module.exports = GameApp;
